{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 环境工具\n",
    "\n",
    "### 环境\n",
    "- 一般用 ipython3交互 可以用Linux命令 代码Tab自动补全 (random.＋Tab)\n",
    "- 开发环境anaconda、开发编辑器pycharm(调试先设置断点debug)\n",
    "- python3.6环境\n",
    "\n",
    "### ipython、jupyter notebook 技巧：\n",
    "- import random；可以用random. 加Tab看下模块有什么\n",
    "- dir(random)  # 查看random模块下有什么函数\n",
    "- help(model_name.func_name)  # 查看模块.函数文档作用\n",
    "- print(func_name.__doc__)  # 同help相当于Linux的man文档\n",
    "- os?  # 可以查看注释\n",
    "- %pwd  # Linux命令\n",
    "\n",
    "### pycharm开发时候技巧\n",
    "- card_main模块、card_tools模块\n",
    "- 利用 # TODO 注释 先标注没有完成功能\n",
    "- Debug 断点调试 F8程序 F7进入函数内部 可以看到局部变量全局变量\n",
    "- 函数记得 写 文档注释 用块注释\"\"\" \"\"\"\n",
    "\n",
    "### python历史\n",
    "- python2用的是ASCII编码支持英文为主\n",
    "- python3用的是unicode，中文支持utf-8\n",
    "- python2的诞生早于unicode\n",
    "- unicode符合python思想通用，只用一种方法\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## python基础知识\n",
    "- 命名规则：小写字母、下划线、数字 ylc_01_变量方法.py\n",
    "- 注释的用法：块注释、单行注释、行注释\n",
    "- 习惯程序计算法-从0开始数数，人类习惯自然计数法-从1开始数数\n",
    "\n",
    "### python符号\n",
    "\n",
    "#### 算术操作符？TODO用表格形式整理\n",
    "- +、-、*、/、//(取整数)、%(取余数)、**(幂)\n",
    "- 优先级：**、% // / *、- + 可以用()修改\n",
    "\n",
    "#### 比较操作符\n",
    "- ==(等于)、!=(不等于)、>、>=、<、<=\n",
    "\n",
    "#### 赋值运算符\n",
    "- = : i = 6 右边6赋值给变量i\n",
    "- 高级用法： i +=1 等同于 i = i + 1 ；*=、//=、\\=、-=等\n",
    "\n",
    "#### 逻辑操作符、成员运算符\n",
    "- 逻辑运算关键字：and、or、not\n",
    "- 成员运算符：\n",
    "    - is、is not \n",
    "    - in、not in \n",
    "\n",
    "### python变量、数据类型\n",
    "\n",
    "#### 变量\n",
    "- 变量定义：存储不同 值 得盒子（数据类型）\n",
    "- 命名规则：word_name_01 ; wordNameYlc\n",
    "- 特定关键字被占用： import key world , keyword.kwlist显示关键字\n",
    "- a = input('请填写输入的内容:') a是str类型计算需要转换\n",
    "\n",
    "#### 数据类型\n",
    "- 数据类型：可以用 type() 查看对象类型 variable;int()、str()、list()等类型转换\n",
    "    - 数字型：int、float、bool(0，1表示 int(True)、int(False) )、complex(pandas科学计算)\n",
    "    - 非数字型：str、list、tuple、dict\n",
    "- 变量是引用data的标签（数据引用），data的存储位置是内存id地址表示 id()\n",
    "- data不可变数据类型：int、bool、str、complex 内存一旦生产id地址不变除非没有变量引用内存回收\n",
    "- data可变数据类型：list、dict 可以在内存id地址不变的前提下list.remove()上面变更\n",
    "    - 这就是为什么不能遍历list中修改list，只能复制一个\n",
    "- dict 中的key由于用的 hash()特征码 所以 key只能是不可变数据类型。\n",
    "\n",
    "### python逻辑运算三大流程\n",
    "- 解释器的运算顺序是：从上而下依次执行，没有分支、循环就没有程序的千变万化\n",
    "- 顺序--从上向下执行代码\n",
    "- 分支--根据条件判断，决定分支 if-elif-else\n",
    "```\n",
    "# 三元操作符\n",
    "small = x if x < y else y\n",
    "level = \"A\" if 100 >= score >=90 else \"B\" if 90 > score >= 80 \\\n",
    "else \"C\" if  80 > score >= 60\n",
    "```\n",
    "- 循环--特定代码块重复执行 while: 条件  块  break/contnue 计步器num\n",
    "```\n",
    "row = 1  # 计数器\n",
    "while row <=9:  #条件\n",
    "    # 代码块\n",
    "    row =+1  # 计数器 避免死循环\n",
    "```\n",
    "```\n",
    "for i in range(10):  # while else、try else 语法一样\n",
    "    pass\n",
    "else:\n",
    "print(\"上面遍历完美运行\")  # 一旦上面被break打断else后就不会运行\n",
    "```\n",
    "\n",
    "### 关键字、函数、方法\n",
    "- import keyworld模块 keyworld.list可以列出 关键字\n",
    "    - del 等不需要()\n",
    "- 内置函数启动自动加载的模块需要记住\n",
    "    - len()、type()、print()、list()、tuple()、hash()、id()、range()、help()、filer()等\n",
    "    ```\n",
    "    def addMe(x):\n",
    "        \"add operation + argument\"  # DocString程序的解释用 addMe.__doc__、help(addMe)\n",
    "        return(x+x)\n",
    "    ```\n",
    "- 方法特殊的函数，用模块加载好的（开发好的标准模块）\n",
    "    - import njyy\n",
    "    - njyy.月_表生成\n",
    "- import this模块 python哲学\n",
    "\n",
    "### 代码结构示意图：\n",
    "```\n",
    "shebnag #! /user/bin/python\n",
    "import 模块\n",
    "全局变量\n",
    "函数、类定义  # 函数闭包\n",
    "main()\n",
    "if __name__ == '__main__': \n",
    "    main()  # 可以用try except 已知错误、未知错误 测试\n",
    "```\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类 OOP（object oriented programmer）\n",
    "#### OOP思路：\n",
    "1. 谁来做，为每个对象给于属性、方法\n",
    "2. 创建类赋值对象 - > 名词\n",
    "3. 不同对象有不同属性、方法互相不关联\n",
    "4. 大驼峰取名法\n",
    "5. 名词 --> 对象 --> 类（对象的抽象）\n",
    "    - 对象 --> 属性（名词）、私有属性\n",
    "    - 对象 --> 方法（动词）、私有方法\n",
    "    - dir(类)：有哪些内置方法\n",
    "    \n",
    "#### OOP实例：\n",
    "#####  画类图\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "#### 类的三大特征：（未完成代码）\n",
    "1. 继承\n",
    "2. 封装\n",
    "3. 多态\n",
    "\n",
    "#### 内置方法：\n",
    "|方法名称|用法|备注\n",
    "|--|--|--|\n",
    "|__doc__|类注释信息显示,help(类)、类.__doc__| def demo(): \"\"\" 注释\"\"\"|\n",
    "|__str__|print(类)打印对象|__str__: retrun \"文字\"|\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 字符串、列表、字典、元组\n",
    "### 字符串\n",
    "- path = r\"C:\\\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模块\n",
    "### 模块基础知识\n",
    "1. 模块的搜索路径顺序\n",
    "    - 模块当前文件夹\n",
    "    - 系统PATH路径\n",
    "    - 要避免当前文件夹模块名和PATH模块名重名，PATH被覆盖\n",
    "2. 模块的存放地址：模块名.__file__ 显示出来；如何自定义搜索模块地址\n",
    "    ```\n",
    "    import sys\n",
    "    sys.path.append(r\"E:\\python模块存放地址\")  # 里面有个 ylc模块 sys.path是模块PATH\n",
    "    import ylc\n",
    "    ```\n",
    "3. 模块的导入方式：\n",
    "    ```\n",
    "    import pandas as pd  # pd是别名标准满足大驼峰命名法 DogModule\n",
    "    from pandas import merge as Me  # pandas模块中导入merge函数别名Me\n",
    "    from pandas import *  # pandas模块导入所有函数与类 如果和上一个模块重名会覆盖上一个模块\n",
    "    ```\n",
    "4. 模块包Package\n",
    "    1. 文件夹名称 ylc_dir：\n",
    "        - __init__.py #  注册表文件\n",
    "        \n",
    "        ```\n",
    "        from . import send_message\n",
    "        from . import receive_message\n",
    "        \n",
    "        ```\n",
    "        - send_message.py  # 文件\n",
    "        ```\n",
    "        def send(char):\n",
    "            print(char)\n",
    "        ```\n",
    "        - receive_message.py  # 文件\n",
    "    2. 应用Package ylc_dir模块：\n",
    "        ```\n",
    "        import ylc_dir\n",
    "        ylc_dir.send_message.send(\"hello\")\n",
    "        ```\n",
    "    \n",
    "5. 发布模块：\n",
    "    [发布模块视频教程](https://www.bilibili.com/video/av14184325/?p=442)\n",
    "    1. 创建setup.py模块\n",
    "    2. 构建模块 python3 setup.py build\n",
    "    3. 生成发布压缩包 python3 sdlist\n",
    "\n",
    "### os模块\n",
    "未完成\n",
    "### sys模块\n",
    "未完成\n",
    "### keyworld模块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 异常\n",
    "- 目的：异常处理是为了标记出已知的错误、与未知的错误\n",
    "- 核心技巧：异常的传递封装，可以不要让代码中写太多的异常\n",
    "\n",
    "```\n",
    "def main():\n",
    "    pass\n",
    "def demo():\n",
    "    return main()  # 主体代码封装\n",
    "    \n",
    "try:\n",
    "    demo()  # 封装代码\n",
    "        \n",
    "    ex = Exception(\"这是一个抛出异常\")  # 用Exception类创建一个自定义异常\n",
    "    if condition:\n",
    "        raise ex  # 抛出异常\n",
    "           \n",
    "except ZeroDivisionError:  # 已知错误\n",
    "    print(\"已知-除零错误\")\n",
    "except Exception as rs:  # 未知错误\n",
    "    print(\"未知错误\")\n",
    "else:\n",
    "    print(\"没有异常就执行这段代码\")\n",
    "finally:\n",
    "    print(\"无论有没有异常都执行\")\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 文件读写操作：\n",
    "### 主要概念\n",
    "1. 打开关闭文件\n",
    "\n",
    "```\n",
    "file = open(path)\n",
    "text = file.read()\n",
    "file.close()\n",
    "```\n",
    "    \n",
    "2. 文件指针\n",
    "3. 读写操作\n",
    "\n",
    "|标记|含义|备注|\n",
    "|:--:|:--:|:--:|\n",
    "|r|只读|rb二进制打开|\n",
    "|w|写操作覆盖原有文件|\n",
    "|a|追加操作|\n",
    "\n",
    "```\n",
    "with open(\"每晚计划.txt\",\"r\") as f:\n",
    "    text = f.read()\n",
    "    print(text)\n",
    "    \n",
    "with open(\"每晚计划.txt\",\"r\") as f:\n",
    "    while True:\n",
    "        text = f.readline()  # 一行一行取\n",
    "        if not text:  # 如果text为空\n",
    "            print(\"文件指针到最后一行退出\")\n",
    "            break\n",
    "        else:\n",
    "            print(text)\n",
    "            \n",
    "```\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 主要函数代码片段\n",
    "### eval()函数\n",
    "- eval()内置函数可以把字符串当做表达式\n",
    "- 注意事项：太危险万一字符串 = \"rm -f\"就悲剧了慎用\n",
    "\n",
    "```\n",
    "print(eval(\"'*'*7\"))  # 结果：*******\n",
    "print(eval(\"1+2\"))  # 结果：3\n",
    "print(eval(\"[1,3,6]\"))  # 结果：[1, 3, 6]\n",
    "\n",
    "input_str = input(\"请输入计算器：\")\n",
    "print(eval(input_str))  # 生成int类型\n",
    "\n",
    "eval(expression, globals=None, locals=None)\n",
    ">>>a, b, c = 1, 2, 3\n",
    " \n",
    ">>>g = {'a': 5, 'b': 10}\n",
    " \n",
    ">>>L = {'b': 50, 'c': 100}\n",
    " \n",
    ">>>eval('a + b + c')   #直接将 a,b,c 三个值相加\n",
    "Out[4]: 6\n",
    " \n",
    ">>>eval('a + b', g)   #当加入参数g后，会覆盖之前变量a,b的值，并将g中的值赋给对应变量\n",
    "Out[5]: 15\n",
    " \n",
    ">>>eval('a + b + c', g)   #当前参与计算的变量必须都在g中，否则报错\n",
    "Traceback (most recent call last):\n",
    " \n",
    "  File \"<ipython-input-5-100c5d3fb1b4>\", line 1, in <module>\n",
    "    eval('a + b + c', g)\n",
    " \n",
    "  File \"<string>\", line 1, in <module>\n",
    " \n",
    "NameError: name 'c' is not defined\n",
    " \n",
    ">>> eval('a + b + c', g, L)  #当加入参数L后，会覆盖之前变量和g中变量值，并将L中的值赋给对应变量\n",
    "Out[7]: 155\n",
    "\n",
    "```\n",
    "### enumerate()函数\n",
    "```\n",
    "s = \"python\"\n",
    "for n,i in enumerate(s):\n",
    "    print(n)  # 数字\n",
    "    print(i)  # 元素\n",
    "```\n",
    "### iter()函数\n",
    "```\n",
    "x = iter(range(2,10,2))  # 生成迭代器\n",
    "next(x)\n",
    "next(x)\n",
    "# 迭代器没有东西会抛出异常 StopIteration\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 小程序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 100元可以换多少1元、2元、5元排列组合\n",
    "i,j,k = 0,0,0 \n",
    "count = 0\n",
    "for i in range(21):  # i代表5元 区间0-20\n",
    "    for j in range(51):  # j代表2元 区间0-50\n",
    "        k = 100 - 5*i - 2*j  # 少一层嵌套关系 k个位数字只要大于0被1整除\n",
    "        if k >=0:            \n",
    "            print(f\"1元{k}个、2元{j}个、5元{i}个\")\n",
    "            count+=1\n",
    "print(f\"总共有{count}组合\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 100元可以换多少1元、2元、5元排列组合\n",
    "count = 0\n",
    "for k in range(0,101):\n",
    "    for j in range(0,101):\n",
    "        for i in range(0,101):\n",
    "            num = k + 2*j + 5*i\n",
    "            if num ==100:\n",
    "                print(f\"1分钱{k}个、2分钱{j}个、5分钱{i}个\")\n",
    "                count+=1\n",
    "print(f\"总共{count}中组合\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['False',\n",
       " 'None',\n",
       " 'True',\n",
       " 'and',\n",
       " 'as',\n",
       " 'assert',\n",
       " 'async',\n",
       " 'await',\n",
       " 'break',\n",
       " 'class',\n",
       " 'continue',\n",
       " 'def',\n",
       " 'del',\n",
       " 'elif',\n",
       " 'else',\n",
       " 'except',\n",
       " 'finally',\n",
       " 'for',\n",
       " 'from',\n",
       " 'global',\n",
       " 'if',\n",
       " 'import',\n",
       " 'in',\n",
       " 'is',\n",
       " 'lambda',\n",
       " 'nonlocal',\n",
       " 'not',\n",
       " 'or',\n",
       " 'pass',\n",
       " 'raise',\n",
       " 'return',\n",
       " 'try',\n",
       " 'while',\n",
       " 'with',\n",
       " 'yield']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import keyword\n",
    "keyword.kwlist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "9 // 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
